{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b518b04cbfe0"
      },
      "source": [
        "##### Copyright 2020 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "906e07f6e562"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "c359f002e834"
      },
      "source": [
        "# TensorFlow Cloud を使用した Keras モデルのトレーニング"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f5c893a15fac"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td><a target=\"_blank\" href=\"https://www.tensorflow.org/guide/keras/training_keras_models_on_cloud\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\">TensorFlow.org で実行</a></td>\n",
        "  <td>     <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/ja/guide/keras/training_keras_models_on_cloud.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\">\tGoogle Colab で実行</a> </td>\n",
        "  <td><a target=\"_blank\" href=\"https://github.com/tensorflow/docs-l10n/blob/master/site/ja/guide/keras/training_keras_models_on_cloud.ipynb\">     <img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\">     GitHubでソースを表示</a></td>\n",
        "  <td>     <a href=\"https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/ja/guide/keras/training_keras_models_on_cloud.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\">ノートブックをダウンロード</a> </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b1c0246f8536"
      },
      "source": [
        "## はじめに\n",
        "\n",
        "[TensorFlow Cloud](https://github.com/tensorflow/cloud) は、ローカルデバッグから Google Cloud 上の分散トレーニングにシームレスに移行する API を提供する Python パッケージです。クラウド上での TensorFlow モデルのトレーニングプロセスを単一のシンプルな関数呼び出しに簡素化して、必要なセットアップを最小限にし、モデルの変更を不要にしました。TensorFlow Cloud は、モデルの VM（仮想マシン）インスタンスや分散ストラテジーの作成など、クラウド固有のタスクを自動的に処理します。このガイドでは、TensorFlow Cloud を通じた Google Cloud とのインターフェース方法と、TensorFlow Cloud 内で提供する幅広い機能について説明します。まずは最もシンプルなユースケースから始めます。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "e015c75faba2"
      },
      "source": [
        "## Setup\n",
        "\n",
        "TensorFlow Cloud をインストールし、このガイドで必要なパッケージのインポートから始めます。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "99e5bc5e0ab8"
      },
      "outputs": [],
      "source": [
        "!pip install -q tensorflow_cloud"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "26113effabca"
      },
      "outputs": [],
      "source": [
        "import tensorflow as tf\n",
        "import tensorflow_cloud as tfc\n",
        "\n",
        "from tensorflow import keras\n",
        "from tensorflow.keras import layers"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "e8568395c87b"
      },
      "source": [
        "## API の概要：最初のエンドツーエンドの例\n",
        "\n",
        "まずは、以下のような CNN の Keras モデルのトレーニングスクリプトから始めましょう。\n",
        "\n",
        "```python\n",
        "(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()\n",
        "\n",
        "model = keras.Sequential(\n",
        "    [\n",
        "        keras.Input(shape=(28, 28)),\n",
        "        # Use a Rescaling layer to make sure input values are in the [0, 1] range.\n",
        "        layers.experimental.preprocessing.Rescaling(1.0 / 255),\n",
        "        # The original images have shape (28, 28), so we reshape them to (28, 28, 1)\n",
        "        layers.Reshape(target_shape=(28, 28, 1)),\n",
        "        # Follow-up with a classic small convnet\n",
        "        layers.Conv2D(32, 3, activation=\"relu\"),\n",
        "        layers.MaxPooling2D(2),\n",
        "        layers.Conv2D(32, 3, activation=\"relu\"),\n",
        "        layers.MaxPooling2D(2),\n",
        "        layers.Conv2D(32, 3, activation=\"relu\"),\n",
        "        layers.Flatten(),\n",
        "        layers.Dense(128, activation=\"relu\"),\n",
        "        layers.Dense(10),\n",
        "    ]\n",
        ")\n",
        "\n",
        "model.compile(\n",
        "    optimizer=keras.optimizers.Adam(),\n",
        "    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n",
        "    metrics=keras.metrics.SparseCategoricalAccuracy(),\n",
        ")\n",
        "\n",
        "model.fit(x_train, y_train, epochs=20, batch_size=128, validation_split=0.1)\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "514f51a9a45d"
      },
      "source": [
        "インポートを始める前にスクリプトの最初に呼び出し `run()` を追加するだけで、このモデルのトレーニングが Google Cloud で行われるようになります。\n",
        "\n",
        "```python\n",
        "tfc.run()\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6e38288bb617"
      },
      "source": [
        "TensorFlow Cloud の使用時には、VM インスタンスの作成や分散ストラテジーなど、クラウド固有のタスクの心配をする必要がありません。API のすべてのパラメータにはインテリジェントなデフォルトが含まれており、すべてのパラメータは構成可能ですが、多くのモデルはこれらのデフォルトに依存しています。\n",
        "\n",
        "`run()` を呼び出すと、TensorFlow Cloud は以下を実行します。\n",
        "\n",
        "- Python スクリプトやノートブックを分散可能な状態にします。\n",
        "- 上記を必要な依存関係を持つ Docker イメージに変換します。\n",
        "- GCP や GPU 搭載の VM 上でトレーニングジョブを実行します。\n",
        "- 関連するログやジョブ情報をストリーム化します。\n",
        "\n",
        "デフォルトの VM 構成は、チーフが 1 個とワーカーが 0 個、CPU 8 コアと Tesla T4 GPU 1 台です。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3ab860e037c9"
      },
      "source": [
        "## Google Cloud の構成\n",
        "\n",
        "適切な Cloud のトレーニングの道筋をつけるためには、多少の新規セットアップが必要です。初めて Google Cloud を利用する場合は、いくらかの予備措置を講じる必要があります。\n",
        "\n",
        "1. GCP プロジェクトを作成する\n",
        "2. AI プラットフォームサービスを有効にする\n",
        "3. サービスアカウントを作成する\n",
        "4. 認証キーをダウンロードする\n",
        "5. Cloud Storage バケットを作成する\n",
        "\n",
        "初回セットアップに関する詳細な手順については、[TensorFlow Cloud README](https://github.com/tensorflow/cloud#setup-instructions) をご覧ください。追加のセットアップ例は [TensorFlow ブログ](https://blog.tensorflow.org/2020/08/train-your-tensorflow-model-on-google.html)に記載されています。\n",
        "\n",
        "## 一般的なワークフローと Cloud Storage\n",
        "\n",
        "大抵の場合は、Google Cloud でトレーニングを行った後にモデルを取得する必要があります。そのためには、リモートトレーニング中に保存と読み込みを Cloud Storage にリダイレクトすることが重要です。TensorFlow Cloud を Cloud Storage バケットに導いて、様々なタスクを行うことができます。ストレージバケットは、大規模なトレーニングデータセットの保存と読み込み、コールバックログやモデル重みの格納、トレーニングモデルファイルの保存に使用することが可能です。まず、`fit()` を構成してモデルを Cloud Storage に保存し、TensorBoard モニタリングをセットアップしてトレーニングの進捗状況をトラッキングしてみましょう。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "af5077731187"
      },
      "outputs": [],
      "source": [
        "def create_model():\n",
        "    model = keras.Sequential(\n",
        "        [\n",
        "            keras.Input(shape=(28, 28)),\n",
        "            layers.experimental.preprocessing.Rescaling(1.0 / 255),\n",
        "            layers.Reshape(target_shape=(28, 28, 1)),\n",
        "            layers.Conv2D(32, 3, activation=\"relu\"),\n",
        "            layers.MaxPooling2D(2),\n",
        "            layers.Conv2D(32, 3, activation=\"relu\"),\n",
        "            layers.MaxPooling2D(2),\n",
        "            layers.Conv2D(32, 3, activation=\"relu\"),\n",
        "            layers.Flatten(),\n",
        "            layers.Dense(128, activation=\"relu\"),\n",
        "            layers.Dense(10),\n",
        "        ]\n",
        "    )\n",
        "\n",
        "    model.compile(\n",
        "        optimizer=keras.optimizers.Adam(),\n",
        "        loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),\n",
        "        metrics=keras.metrics.SparseCategoricalAccuracy(),\n",
        "    )\n",
        "    return model\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5f2e65d8f3a6"
      },
      "source": [
        "トレーニング中に生成された TensorBoard のログとモデルのチェックポイントをクラウド ストレージバケットに保存してみましょう。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "fdc4f951281c"
      },
      "outputs": [],
      "source": [
        "import datetime\n",
        "import os\n",
        "\n",
        "# Note: Please change the gcp_bucket to your bucket name.\n",
        "gcp_bucket = \"keras-examples\"\n",
        "\n",
        "checkpoint_path = os.path.join(\"gs://\", gcp_bucket, \"mnist_example\", \"save_at_{epoch}\")\n",
        "\n",
        "tensorboard_path = os.path.join(  # Timestamp included to enable timeseries graphs\n",
        "    \"gs://\", gcp_bucket, \"logs\", datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n",
        ")\n",
        "\n",
        "callbacks = [\n",
        "    # TensorBoard will store logs for each epoch and graph performance for us.\n",
        "    keras.callbacks.TensorBoard(log_dir=tensorboard_path, histogram_freq=1),\n",
        "    # ModelCheckpoint will save models after each epoch for retrieval later.\n",
        "    keras.callbacks.ModelCheckpoint(checkpoint_path),\n",
        "    # EarlyStopping will terminate training when val_loss ceases to improve.\n",
        "    keras.callbacks.EarlyStopping(monitor=\"val_loss\", patience=3),\n",
        "]\n",
        "\n",
        "model = create_model()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "45d6210176e6"
      },
      "source": [
        "ここでは、直接 Keras からデータをロードします。一般的にはデータセットをクラウドストレージのバケットに格納するのがベストプラクティスですが、TensorFlow Cloud はローカルに格納されているデータセットにも対応可能です。これについては、このガイドのマルチファイルに関するセクションで説明しています。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "bd4ef6ffa611"
      },
      "outputs": [],
      "source": [
        "(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b1d2a2688887"
      },
      "source": [
        "[TensorFlow Cloud](https://github.com/tensorflow/cloud) API は、ローカルとクラウド上のどちらでコードを実行するかを決める、`remote()` 関数を用意しています。これにより、`fit()` パラメータをローカル実行とリモート実行に分けて指定することができ、ローカルマシンに負荷をかけることなく容易にデバッグする手段を提供します。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "cfab9ff41fd5"
      },
      "outputs": [],
      "source": [
        "if tfc.remote():\n",
        "    epochs = 100\n",
        "    callbacks = callbacks\n",
        "    batch_size = 128\n",
        "else:\n",
        "    epochs = 5\n",
        "    batch_size = 64\n",
        "    callbacks = None\n",
        "\n",
        "model.fit(x_train, y_train, epochs=epochs, callbacks=callbacks, batch_size=batch_size)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9b27c0b3b7db"
      },
      "source": [
        "トレーニングが終了したら、モデルを GCS に保存しましょう。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "b00451dcfeab"
      },
      "outputs": [],
      "source": [
        "save_path = os.path.join(\"gs://\", gcp_bucket, \"mnist_example\")\n",
        "\n",
        "if tfc.remote():\n",
        "    model.save(save_path)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0dceb5b7a173"
      },
      "source": [
        "Docker イメージの構築には、ローカルの Docker インスタンスの代わりに、このストレージバケットを使用することもできます。`docker_image_bucket_name` パラメータにバケットを追加するだけで、これが可能になります。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "13200523ed93"
      },
      "outputs": [],
      "source": [
        "# docs_infra: no_execute\n",
        "tfc.run(docker_image_bucket_name=gcp_bucket)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "060a2112c34e"
      },
      "source": [
        "モデルをトレーニングした後は、保存したモデルを読み込み、パフォーマンスを監視するために TensorBoard のログを表示します。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "b8d773e2cfb7"
      },
      "outputs": [],
      "source": [
        "# docs_infra: no_execute\n",
        "model = keras.models.load_model(save_path)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "05d1d68bae5a"
      },
      "outputs": [],
      "source": [
        "!#docs_infra: no_execute\n",
        "!tensorboard dev upload --logdir \"gs://keras-examples-jonah/logs/fit\" --name \"Guide MNIST\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3785ece03a8f"
      },
      "source": [
        "## 大規模プロジェクト\n",
        "\n",
        "多くの場合、Keras モデルを含むプロジェクトは複数の Python スクリプトを含んでいたり、外部データや特定の依存関係を必要としたりします。TensorFlow Cloud は、大規模デプロイメントに完全な柔軟性があり、プロジェクトを支援する多くのインテリジェントな機能を提供します。\n",
        "\n",
        "### エントリーポイント：Python スクリプトと Jupyter ノートブックのサポート\n",
        "\n",
        "`run()` API を呼び出しても、それが必ずモデルトレーニングコードと同じ Python スクリプト内に含まれているとは限りません。そのため、`entry_point` パラメータを用意しています。`entry_point` パラメータは、モデルトレーニングコードが置かれている Python スクリプトやノートブックの指定に使用できます。モデルと同じスクリプトから `run()` を呼び出す場合は、`entry_point` のデフォルトである `None` を使用します。\n",
        "\n",
        "### `pip` 依存関係\n",
        "\n",
        "プロジェクトが追加の `pip` 依存関係を呼び出す場合は、`requirements.txt` ファイルをインクルードして必要な追加のライブラリを指定することができます。このファイル内に必要な依存関係のリストを書き込むだけで、TensorFlow Cloud がそれらをクラウドビルドに統合する処理を行います。\n",
        "\n",
        "### Python ノートブック\n",
        "\n",
        "TensorFlow Cloud は Python ノートブックからも実行可能です。さらに、指定した `entry_point` は必要に応じてノートブックにすることができます。ノートブック上の TensorFlow Cloud をスクリプトと比較した場合、念頭に置いておいた方がよい重要な違いが 2 点あります。\n",
        "\n",
        "- ノートブック内から `run()` を呼び出す際に、Docker イメージを構築して格納するために Cloud Storage バケットを指定する必要があります。\n",
        "- Google Cloud 認証はすべて認証キーを使用して行い、プロジェクトを指定する必要はありません。ノートブックから TensorFlow Cloud を使用するワークフローの例は、本ガイドの「すべてを統合する」セクションで紹介しています。\n",
        "\n",
        "### マルチファイルプロジェクト\n",
        "\n",
        "モデルが追加ファイルに依存する場合、ここではそれらのファイルを必ず指定されたエントリポイントと同じディレクトリ（またはサブディレクトリ）に置くようにするだけです。指定した `entry_point` と同じディレクトリ内に格納されているすべてのファイルは、`entry_point` に隣接するサブディレクトリに格納されているファイルと同様に、Docker イメージにインクルードされます。これは `pip` では取得できない依存関係が必要な場合にも該当します。\n",
        "\n",
        "追加の pip 依存関係を持つカスタムエントリーポイントとマルチファイルプロジェクトの例は、[TensorFlow Cloud Repository](https://github.com/tensorflow/cloud/tree/master/src/python/tensorflow_cloud/core/tests/examples/multi_file_example) にあるマルチファイルの例をご覧ください。簡潔にするために、ここでは例の `run()` 呼び出しのみをインクルードします。\n",
        "\n",
        "```python\n",
        "tfc.run(\n",
        "    docker_image_bucket_name=gcp_bucket,\n",
        "    entry_point=\"train_model.py\",\n",
        "    requirements=\"requirements.txt\"\n",
        ")\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "997e3f89c734"
      },
      "source": [
        "## マシン構成と分散トレーニング\n",
        "\n",
        "モデルのトレーニングには、モデルやデータセットの大きさ次第で、幅広く異なったリソースを必要とする可能性があります。複数の GPU を使用した構成を考慮する場合、適合する[分散ストラテジー](https://www.tensorflow.org/guide/distributed_training)を選択することが重要になります。ここでは、可能性のある構成をいくつか概説します。\n",
        "\n",
        "### マルチワーカー分散\n",
        "\n",
        "ここでは、`COMMON_MACHINE_CONFIGS`を使用して、チーフ CPU 1 個、ワーカー GPU 4 個を指定します。\n",
        "\n",
        "```python\n",
        "tfc.run(\n",
        "    docker_image_bucket_name=gcp_bucket,\n",
        "    chief_config=tfc.COMMON_MACHINE_CONFIGS['CPU'],\n",
        "    worker_count=2,\n",
        "    worker_config=tfc.COMMON_MACHINE_CONFIGS['T4_4X']\n",
        ")\n",
        "```\n",
        "\n",
        "デフォルトでは、TensorFlow Cloudは提供された`chief_config`、`worker_config`、`worker_count`パラメータを使用する単純な式で、マシン構成に最適な分散ストラテジーを選択します。\n",
        "\n",
        "- 指定した GPU の数が 0 より大きい場合は、`tf.distribute.MirroredStrategy`が選択されます。\n",
        "- ワーカーの数が 0 より大きい場合は、アクセラレータの種類に応じて`tf.distribution.experimental.MultiWorkerMirroredStrategy`または`tf.distribution.experimental.TPUStrategy`が選択されます。\n",
        "- それ以外の場合は、`tf.distribute.OneDeviceStrategy`が選択されます。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "e0d938efab72"
      },
      "source": [
        "### TPU 分散\n",
        "\n",
        "以下のように TPU 上で同じモデルをトレーニングしてみましょう。\n",
        "\n",
        "```python\n",
        "tfc.run(\n",
        "    docker_image_bucket_name=gcp_bucket,\n",
        "    chief_config=tfc.COMMON_MACHINE_CONFIGS[\"CPU\"],\n",
        "    worker_count=1,\n",
        "    worker_config=tfc.COMMON_MACHINE_CONFIGS[\"TPU\"]\n",
        ")\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "d1dec83a0b19"
      },
      "source": [
        "### カスタム分散ストラテジー\n",
        "\n",
        "カスタム分散ストラテジーを指定するには、[分散トレーニングガイド](https://www.tensorflow.org/guide/distributed_training)に従って通常通りにコードをフォーマットし、`distribution_strategy` を `None` 設定にします。以下では、同じ MNIST モデルに独自の分散ストラテジーを指定します。\n",
        "\n",
        "```python\n",
        "(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()\n",
        "\n",
        "mirrored_strategy = tf.distribute.MirroredStrategy()\n",
        "with mirrored_strategy.scope():\n",
        "  model = create_model()\n",
        "\n",
        "if tfc.remote():\n",
        "    epochs = 100\n",
        "    batch_size = 128\n",
        "else:\n",
        "    epochs = 10\n",
        "    batch_size = 64\n",
        "    callbacks = None\n",
        "\n",
        "model.fit(\n",
        "    x_train, y_train, epochs=epochs, callbacks=callbacks, batch_size=batch_size\n",
        ")\n",
        "\n",
        "tfc.run(\n",
        "    docker_image_bucket_name=gcp_bucket,\n",
        "    chief_config=tfc.COMMON_MACHINE_CONFIGS['CPU'],\n",
        "    worker_count=2,\n",
        "    worker_config=tfc.COMMON_MACHINE_CONFIGS['T4_4X'],\n",
        "    distribution_strategy=None\n",
        ")\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0a50b62bf672"
      },
      "source": [
        "## カスタム Docker イメージ\n",
        "\n",
        "デフォルトでは、TensorFlow Cloud は Google が提供する [Docker ベースイメージ](https://hub.docker.com/r/tensorflow/tensorflow/)を使用するので、現在の TensorFlow バージョンに対応します。しかし、必要に応じて構築要件に合わせたカスタム Docker イメージを指定することも可能です。この例では、古い TensorFlow バージョンから Docker イメージを指定します。\n",
        "\n",
        "```python\n",
        "tfc.run(\n",
        "    docker_image_bucket_name=gcp_bucket,\n",
        "    base_docker_image=\"tensorflow/tensorflow:2.1.0-gpu\"\n",
        ")\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bb659015ffad"
      },
      "source": [
        "## その他のメトリクス\n",
        "\n",
        "Cloud ジョブに固有のラベルを付けたり、Cloud トレーニング中にモデルのログをストリーム化したりすると有用な場合があります。記録を管理できるように、すべての Cloud ジョブに適切なラベル付けをすることをお勧めします。そのために、`run()` は最大 64 ペアまでキーと値のラベルのディクショナリを受け入れることができ、これは Cloud のビルドログに表示されます。エポックのパフォーマンスやモデルの保存内部などに関するログは、`tfc.run` を実行して提供されるリンクを使用してアクセスするか、`stream_logs` フラグを使用してローカルターミナルに出力することが可能です。\n",
        "\n",
        "```python\n",
        "job_labels = {\"job\": \"mnist-example\", \"team\": \"keras-io\", \"user\": \"jonah\"}\n",
        "\n",
        "tfc.run(\n",
        "    docker_image_bucket_name=gcp_bucket,\n",
        "    job_labels=job_labels,\n",
        "    stream_logs=True\n",
        ")\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "b34a2e8e09c3"
      },
      "source": [
        "## すべてを統合する\n",
        "\n",
        "このガイドで説明した特徴の多くを用いた、さらに深い Colab については、[こちらの例](https://github.com/tensorflow/cloud/blob/master/src/python/tensorflow_cloud/core/tests/examples/dogs_classification.ipynb)に従って特徴抽出を使用し、写真から犬の品種を認識する最先端モデルのトレーニングを行います。"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [],
      "name": "training_keras_models_on_cloud.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
